<template>
  <el-card style="text-align: center;margin-bottom: 20px">
    <CategorySelect @doChange="getCateGoryId" :show="!isShowTable"></CategorySelect>
  </el-card>
  <el-card>
    <!--平台属性列表的表格-->
    <div v-show="isShowTable">
      <el-button type="primary" style="margin-bottom: 10px" :disabled="!categoryThreeId" @click="addAttr">
        <el-icon>
          <Plus/>
        </el-icon>
        添加属性
      </el-button>
      <el-table height="300px" border :data="attrList">
        <el-table-column label="序号" type="index" width="100px"></el-table-column>
        <el-table-column label="属性名称" prop="attrName"></el-table-column>
        <el-table-column label="属性值列表">
          <template v-slot="{row}">
            <el-tag type="success" v-for="attrValue in row.attrValueList" :key="attrValue.id"
                    style="margin-right: 10px;margin-bottom: 5px">{{ attrValue.valueName }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{row}">
            <el-button type="warning" @click="updateAttr(row)">
              <el-icon>
                <EditPen/>
              </el-icon>
              编辑
            </el-button>
            <el-button type="danger">
              <el-icon>
                <Delete/>
              </el-icon>
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!--添加或者修改属性的结构-->
    <div v-show="!isShowTable">
      <el-form inline="true" label-width="80px" :model="attrInfo">
        <el-form-item label="属性名">
          <el-input placeholder="请输入属性名" v-model="attrInfo.attrName"></el-input>
        </el-form-item>
      </el-form>
      <el-button type="primary" @click="addAttrValue" :disabled="!attrInfo.attrName">
        <el-icon>
          <Plus/>
        </el-icon>
        添加属性值
      </el-button>
      <el-button>取消</el-button>
      <el-table style="margin:10px 0" height="300px" border :data="attrInfo.attrValueList">
        <el-table-column label="序号" type="index" width="100px"></el-table-column>
        <el-table-column label="属性值名称" prop="attrName">
          <template v-slot="{row}">
            <!--这里需要span和input来回切换-->
            <el-input ref="attrInput" v-model="row.valueName" placeholder="请输入属性值名称" size="small" v-if="row.isShowInput"
                      @blur="toLook(row)"></el-input>
            <span v-else @click="toEdit(row)" style="display: block">{{ row.valueName }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{row,index}">
            <el-popconfirm :title="`确认要删除${row.valueName}这条属性吗?`" confirm-button-text="是" cancel-button-text="否"
                           icon-color="red" @confirm="deleteAttrValue(index)">
              <template #reference>
                <el-button type="danger" size="small">
                  <el-icon>
                    <Delete/>
                  </el-icon>
                </el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <el-button type="primary" @click="addOrUpdateAttr" :disabled="attrInfo.attrValueList.length < 1">保存</el-button>
      <el-button type="warning" @click="isShowTable = true">取消</el-button>
    </div>
  </el-card>
</template>

<script>
import CategorySelect from "../../components/CategorySelect";
import {reqAddOrUpdateAttr, reqAttrList} from "../../api/realRequests";
import {ElMessage} from "element-plus";

export default {
  name: "Attr",
  components: {CategorySelect},
  data() {
    return {
      // 用来接受子组件传来的一，二，三级id
      categoryOneId: '',
      categoryTwoId: '',
      categoryThreeId: '',
      // 平台属性列表
      attrList: [],
      // 控制是否显示表格
      isShowTable: true,
      // 收集属性信息，在 新增属性或者修改属性 时使用(数据结构和类型由后端决定，不能瞎写)
      attrInfo: {
        // 属性名
        attrName: '',
        // 属性值，一个属性名的属性值可以有多个，所以用数组，每个属性值都有id,所以把每个值和对应的id当做一个对象
        attrValueList: [
          // {
          //   attrName: '1',
          //   valueName: '1'
          // }
        ],
        // 三级分类的id
        categoryId: undefined,
        // 服务器要区分是几级id
        categoryLevel: 3
      },
      // 输入框和span的切换
      isShowInput: true
    }
  },
  methods: {
    // 父组件接受，自定事件的回调(params就是子组件传来的对象，形参)
    getCateGoryId(params) {
      // 接受子组件传来的值
      this.categoryOneId = params.category1Id
      this.categoryTwoId = params.category2Id
      this.categoryThreeId = params.category3Id
      // 调方法，获得数据
      this.getAttrList()
    },
    // 获取平台属性的数据
    async getAttrList() {
      let result = await reqAttrList(this.categoryOneId, this.categoryTwoId, this.categoryThreeId)
      // console.log(result)
      if (result.code == 200) {
        this.attrList = result.data
      }
    },
    // 修改属性
    updateAttr(row) {
      this.isShowTable = false
      //将选中要修改的行的数据赋值给attrInfo
      //由于数据结构当中存在对象里面套数组，数组里面有套对象，因此需要使用深拷贝解决这类问题Ⅰ
      this.attrInfo = JSON.parse(JSON.stringify(row))
      //在修改某一个属性的时候，将相应的属性值元素添加上isShowInput这个属性，并附默认值false
      this.attrInfo.attrValueList.forEach(item => {
        // vue2中使用 $set 向对象身上添加响应式属性，$set(对象名,想要添加的属性名，添加的属性的值)
        // this.$set(item, 'isShowInput', false)
        item.isShowInput = false
      })
    },
    // 添加属性
    addAttr() {
      // 切换当前table的显示与隐藏
      this.isShowTable = false
      // 清除上次输入框和表格的数据，并收集三级分类的id
      this.attrInfo = {
        attrName: '',
        attrValueList: [],
        categoryId: this.categoryThreeId,
        categoryLevel: 3
      }
    },
    // 添加属性值
    addAttrValue() {
      this.attrInfo.attrValueList.unshift({
        attrName: this.attrInfo.id,
        valueName: undefined,
        // 给每一个属性值添加一个状态，用于控制输入框和span的切换
        isShowInput: true
      })
      // 点击添加属性值后，自动聚焦到第一个新增input
      this.$nextTick(() => {
        this.$refs.attrInput.focus()
      })
    },
    // 输入框失焦时的判断
    toLook(row) {
      // 如果输入的属性值为空，则不能作为新属性值，给用户提示，重新输入
      if (row.valueName.trim() == '') {
        ElMessage({type: 'error', message: '输入为空，请重新输入！', duration: 2000, center: true})
        return
      }
      // 且新增的属性值不能与已有值重复
      let isRepat = this.attrInfo.attrValueList.some(item => {
        // 需要将当前输入行从判断的数组元素中去除
        if (row !== item) {
          return row.valueName == item.valueName
        }
      })
      // 如果输入的属性值已经存在
      if (isRepat == true) {
        ElMessage({type: 'error', message: '属性值重复，请重新输入！', duration: 2000, center: true})
        return
      } else {
        // 如果输入的属性值不存在
        // ElMessage({type: 'success', message: '新属性值有效！', duration: 2000, center: true})
      }
      // 切换输入框的状态为span的状态
      row.isShowInput = false
    },
    // 点击span时的回调
    toEdit(row) {
      // 将span切换为input
      row.isShowInput = true
      // console.log(index)
      // 获取当前点击的input节点，实现自动聚焦
      // 需要注意:点击span的时候，将span切换为input，但是这个过程需要时间，因为浏览器要对页面进行重绘与重排，
      // 因此我们不可能点击span立码获取到input，所以采用 $nextTick,当节点渲染完毕了，才会执行内部的代码
      this.$nextTick(() => {
        console.log(this.$refs.attrInput)
        this.$refs.attrInput.focus()
      })
      // 也可以使用延时器达到相同的效果
      // setTimeout(() => {
      //   this.$refs.attrInput.focus()
      //   console.log(222222)
      // }, 0)
    },
    // 点击删除的气泡确定框的确定按钮时的回调
    deleteAttrValue(index) {
      console.log(index)
      // 当前删除操作不要要发请求
      this.attrInfo.attrValueList.splice(index, 1)
    },
    //
    async addOrUpdateAttr() {
      // 整理参数：1.
      this.attrInfo.attrValueList = this.attrInfo.attrValueList.filter(item => {
        if (item.valueName != '') {
          delete item.isShowInput
          return true
        }
      })
      try {
        await reqAddOrUpdateAttr(this.attrInfo)
        ElMessage({type: 'success', message: '保存成功！', duration: 2000, center: true})
        await this.getAttrList()
        this.isShowTable = true
      } catch (error) {
        ElMessage({type: 'error', message: '保存失败！', duration: 2000, center: true})
      }
    }
  }
}
</script>

<style scoped>

</style>